package com.itheima.app.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.FocusUser;
import com.itheima.domain.mongo.Video;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.FocusUserService;
import com.itheima.service.mongo.VideoService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.CommentVo;
import com.itheima.vo.ErrorResult;
import com.itheima.vo.PageBeanVo;
import com.itheima.vo.VideoVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class VideoManager {

    @DubboReference
    private VideoService videoService;

    @DubboReference
    private UserInfoService userInfoService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @DubboReference
    private CommentService commentService;

    @Autowired
    private MQVideoManager mqVideoManager;

    //推荐视频分页
    public ResponseEntity findRecommendVideoVoByPage(Long userId, Integer pageNum, Integer pageSize) {

        PageBeanVo pageBeanVo = videoService.findRecommendVideoByPage(userId, pageNum, pageSize);

        List<VideoVo> voList = new ArrayList<>();

        List<Video> videoList = (List<Video>) pageBeanVo.getItems();

        if (CollectionUtil.isNotEmpty(videoList)) {
            for (Video video : videoList) {
                VideoVo vo = new VideoVo();
                UserInfo userInfo = userInfoService.findById(video.getUserId());
                vo.setUserInfo(userInfo);
                vo.setVideo(video);
                //是否有关注
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.FOCUS_USER, userId, video.getUserId()))) {
                    vo.setHasFocus(1);

                }
                //是否有点赞
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.VIDEO_LIKE, userId, video.getId()))) {
                    vo.setHasLiked(1);
                }
                voList.add(vo);
            }
        }

        pageBeanVo.setItems(voList);

        return ResponseEntity.ok(pageBeanVo);
    }

    @Autowired
    private FastFileStorageClient client;
    @Autowired
    private FdfsWebServer webServer;
    //发布视频
    public ResponseEntity publishVideo(Long userId, MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {
        //查询是否封禁
        if (stringRedisTemplate.hasKey(ConstantUtil.FREEZE_PUBLISH + userId)) {
            return ResponseEntity.status(500).body(ErrorResult.publishFreezeError());
        }
        //上传封面
        StorePath storePath1 = client.uploadFile(videoThumbnail.getInputStream(), videoThumbnail.getSize(),
                FileUtil.extName(videoThumbnail.getOriginalFilename()), null);
        String picUrl = webServer.getWebServerUrl() + storePath1.getFullPath();
        //上传视频
        StorePath storePath2 = client.uploadFile(videoFile.getInputStream(), videoFile.getSize(),
                FileUtil.extName(videoFile.getOriginalFilename()), null);
        String videoUrl = webServer.getWebServerUrl() + storePath2.getFullPath();

        Video video = new Video();
        video.setId(ObjectId.get());
        video.setCreated(System.currentTimeMillis());
        video.setUserId(userId);
        video.setPicUrl(picUrl);
        video.setVideoUrl(videoUrl);
        videoService.publishVideo(video);
        return ResponseEntity.ok(null);
    }

    @DubboReference
    private FocusUserService focusUserService;

    //关注用户
    public void saveFocusUser(Long userId, Long focusUserId) {
        FocusUser focusUser = new FocusUser();
        focusUser.setCreated(System.currentTimeMillis());
        focusUser.setUserId(userId);
        focusUser.setFocusUserId(focusUserId);
        focusUserService.saveFocusUser(focusUser);
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.FOCUS_USER, userId, focusUserId), "1");


    }
    //取消关注
    public void removeFocusUser(Long userId, Long focusUserId) {
        focusUserService.removeFocusUser(userId, focusUserId);
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.FOCUS_USER, userId, focusUserId));
    }
    //视频点赞
    public ResponseEntity videoLike(String publishId) {
        // 1.获取线程内userId
        Long userId = UserHolder.get().getId();
        // 2.查询视频详情
        Video video = videoService.findById(new ObjectId(publishId));
        // 3.封装comment
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(video.getId());
        comment.setCommentType(4);
        comment.setUserId(userId);
        comment.setPublishUserId(video.getUserId());
        // 4.调用rpd保存
        Integer likeCount = commentService.saveComment(comment);

        // 5. 向redis中存储标记  video_like:{userId}_{publishId} = 1
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.VIDEO_LIKE, userId, publishId), "1");

        //发送mq消息
        mqVideoManager.sendMovement(userId, video.getId(), MQVideoManager.VIDEO_LIKE);
        // 6.返回点赞数量
        return ResponseEntity.ok(likeCount);

    }
    //视频取消点赞
    public ResponseEntity videoDislike(String publishId) {
        //获取线程内用户id
        Long userId = UserHolder.get().getId();
        // 2.调用rpc删除（三个条件）
        Integer count = commentService.removeComment(new ObjectId(publishId), userId, 4);
        // 3.从reids中删除点赞标记
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.VIDEO_LIKE, userId, publishId));
        //发送mq消息
        mqVideoManager.sendMovement(userId, new ObjectId(publishId), MQVideoManager.VIDEO_DISLIKE);

        //返回点赞数量
        return ResponseEntity.ok(count);

    }

    //视频评论分页
    public ResponseEntity findCommentByPage(String publishId, Integer pageNum, Integer pageSize) {
        Long userId = UserHolder.get().getId();
        //调用rpc分页
        PageBeanVo pageBeanVo = commentService.findCommentByPage(new ObjectId(publishId), 5, pageNum, pageSize);
        //创建volist
        List<CommentVo> volist = new ArrayList<>();
        //获取分页里的数据
        List<Comment> commentList = (List<Comment>) pageBeanVo.getItems();
        if (CollectionUtil.isNotEmpty(commentList)) {
            for (Comment comment : commentList) {
                UserInfo userInfo = userInfoService.findById(comment.getUserId());
                CommentVo vo = new CommentVo();
                vo.setId(comment.getId().toHexString());
                vo.setAvatar(userInfo.getAvatar());
                vo.setNickname(userInfo.getNickname());
                vo.setContent(comment.getContent());
                vo.setCreateDate(DateUtil.formatDateTime(new Date(comment.getCreated())));
                vo.setLikeCount(comment.getLikeCount());
                //判断是否点赞
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.COMMENT_LIKE, userId, comment.getId()))) {
                    vo.setHasLiked(1);
                }
                //添加到集合
                volist.add(vo);
            }
        }
        pageBeanVo.setItems(volist);
        return ResponseEntity.ok(pageBeanVo);
    }

    //发布评论
    public ResponseEntity videoComment(String publishId, String comment) {
        //获取线程内userId
        Long userId = UserHolder.get().getId();
        if (stringRedisTemplate.hasKey(ConstantUtil.FREEZE_COMMENT + userId)) {
            return ResponseEntity.status(500).body(ErrorResult.commentFreezeError());
        }
        //查询动态
        Video video = videoService.findById(new ObjectId(publishId));

        Comment comment1 = new Comment();
        comment1.setCreated(System.currentTimeMillis());
        comment1.setPublishUserId(video.getUserId());
        comment1.setCommentType(5);
        comment1.setUserId(userId);
        comment1.setPublishId(video.getId());
        comment1.setContent(comment);
        Integer count = commentService.saveComment(comment1);
        //发送mq消息
        mqVideoManager.sendMovement(userId, video.getId(), MQVideoManager.VIDEO_COMMENT);

        return ResponseEntity.ok(count);
    }


    //评论点赞
    public ResponseEntity commentLike(String publishId) {
        Long userId = UserHolder.get().getId();
        Comment publishComment = commentService.findById(new ObjectId(publishId));
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(publishComment.getId());
        comment.setCommentType(6);
        comment.setUserId(userId);
        comment.setPublishUserId(publishComment.getUserId());
        Integer count = commentService.saveComment(comment);
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.COMMENT_LIKE, userId, publishId), "1");
        return ResponseEntity.ok(count);
    }

    //评论取消点赞
    public ResponseEntity commentDislike(String publishId) {
        Long userId = UserHolder.get().getId();
        Integer count = commentService.removeComment(new ObjectId(publishId), userId, 6);
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.COMMENT_LIKE, userId, publishId));
        return ResponseEntity.ok(count);

    }


}
